{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Kinetic Monte-Carlo Simulation Notebook\n",
    "* This notebook is for running a KMC simulation\n",
    "* Set relevant parameters and create simulation object\n",
    "* Extract relevent results"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Import modules"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import time\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "import ipywidgets as widgets\n",
    "\n",
    "import KMC_Main_v3p4p1 as KMC_Main\n",
    "import KMC_Processes_v3p4p1 as KMC_Proc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Set Parameters"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Parameters = {}     # Create Parameters Dictionary\n",
    "\n",
    "Parameters['Current_Version'] = 'v3.4.1'   # version of KMC running\n",
    "\n",
    "\n",
    "# Simulation Parameters\n",
    "Parameters['Project_Name'] = 'Test'      # Name for the project save directory.\n",
    "Parameters['Simulation_Name'] = 'test'          # Name of particular simulation within a project. Can be an empty string, '', because it's DateTime stamped\n",
    "\n",
    "Parameters['Enable_Print_Outs'] = True          # Enable/Disable simulation prinouts.\n",
    "Parameters['Enable_Plots'] = True               # Display final plots at end of simulation. Set to False if running multiple simulations\n",
    "\n",
    "Parameters['Solver_Type'] = 'Binary'            # Type of Solver: 'Linear' O(N^2), 'Binary' O(N log N), 'Set' O(N log N) (currently not wokring)\n",
    "\n",
    "Parameters['Simulation_Type'] = 'Deposition'    # Simulation Type. Choices: 'Deposition', 'Diffusion', 'Density', 'Ising' (future)\n",
    "Parameters['Dimension'] = '3D'                  # Either 2D (1+1) or 3D (2+1). For 2D only Lx is used.\n",
    "\n",
    "Parameters['Number_of_Simulations'] = 1         # Number of back-to-back simulations to perform (fixed parameters). Analysis results will be averaged.\n",
    "\n",
    "\n",
    "\n",
    "# Save Data Parameters - (Note: Data is now saved at each analysis time step)\n",
    "Parameters['Save_All_Events'] = False          # Saves all events in the simulation to output file.\n",
    "Parameters['Save_Lattice'] = False             # Save snapshot of lattice at specified times.\n",
    "Parameters['Save_Surface'] = False             # Save a top down view of surface at specified times.\n",
    "Parameters['Save_Time_Step'] = 0.5             # Time interval to save lattice and statistics data (set to resolution needed for post analysis). Also for Progress Bar update.\n",
    "Parameters['Save_with_Analysis'] = False       # Save data at same time as analysis. This overrides the above time step (though it is still used for progress bar). \n",
    "\n",
    "\n",
    "\n",
    "# On-the-Fly Analysis Parameters - Note: currently only enabled for 3D Deposition simulations\n",
    "Parameters['Coverage'] = True                  # do a coverage analysis\n",
    "Parameters['Island_Analysis'] = False           # do island size distribution analysis\n",
    "Parameters['Structure_Factor'] = False          # do structure factor analysis\n",
    "Parameters['Gaussian_Filter'] = 1.0            # apply gaussian filter to SF analysis. 0 = no filter, > 0 = sigma value\n",
    "\n",
    "Parameters['Analysis_Style'] = 'time'              # choose whether to analyze simulation by time step ('time') or simulation steps ('step')\n",
    "Parameters['Analysis_Time_Spacing'] = 'quad'     # delta t spacing of analysis points. Options: 'linear', 'quad', 'log'. For 'log' this is time of first data point\n",
    "Parameters['Log_Points'] = 200                     # For log spacing option only. This is the number of points per pulse. Set 'Analysis_Delta_Time' to be the first analysis point\n",
    "\n",
    "Parameters['Analysis_Delta_Time'] = 1e-2      # time interval for On-the-Fly analysis in seconds. Set 'Analysis_Style' to 'time'\n",
    "Parameters['Analysis_Delta_Step'] = 1e4      # step interval for On-the-Fly analysis. This will result in non-linear time step for analysis points. Set 'Analysis_Style' to 'step'\n",
    "\n",
    "Parameters['On_the_Fly_Save'] = False         # whether to save the on-the-fly results for each simulation. Usually true, unless doing multiple simulations.\n",
    "Parameters['Average_Results'] = False          # average on-the-fly results and save across mulit-simulations. Only used when running multiple simulations.\n",
    "\n",
    "\n",
    "\n",
    "# Substrate Parameters\n",
    "Parameters['Lx'] = 200                   # Substrate size in x direction\n",
    "Parameters['Ly'] = 200                   # Substrate size in y direction (not used in 2D mode)\n",
    "Parameters['depth'] = 15                 # Substrate size in z direction. Give yourself enough layers. (be careful setting this, or errors could occur)\n",
    "\n",
    "Parameters['Substrate_Type'] = 'Flat'           # Substrate Type. Options: 'Flat', 'Islands', 'Steps', 'Custom'\n",
    "\n",
    "Parameters['Feature_Grid'] = 'Square'             # Feature Grid: 'Square', 'Hex': Hexagonal. This is for 'Islands' type only.\n",
    "Parameters['Feature_Layout'] = 'Uniform'          # Feature Layout: 'Uniform': uniform grid, 'Correlated': random offset from uniform , 'Random': random layout\n",
    "Parameters['Feature_Spacing'] = (20,20,0)         # (number in x direction, number in y, avg spread of features (sigma)). For 'Islands' only.\n",
    "\n",
    "Parameters['Size_Distribution'] = 'Gaussian'        # Size ditribution of features: 'None', 'Gaussian', or 'Correlated'\n",
    "Parameters['Size_Values'] = (5,1,0)                # (Avg Radius or Step Length, Height of features, Width of distribution)\n",
    "\n",
    "Parameters['Substrate_Particle_State'] = 'Passive'      # Whether substrate particles are active or not. Options: 'Active', 'Passive'.\n",
    "\n",
    "Parameters['Substrate_File'] = 'Surface_Cov0.7987.npy'          # For custom substrate, name of coordinates file. File must be in same directory as simulation script.\n",
    "\n",
    "\n",
    "\n",
    "# Deposition Parameters (Deposition type simulations only)\n",
    "Parameters['Deposition_Type'] = 'PLD'              # Type of deposition simulation. Options: 'PLD' or 'MBE'\n",
    "Parameters['Pulses_per_Layer'] = 20                # number of pulses per monolayer. For PLD only\n",
    "Parameters['Layers'] = 0.8                        # number of monolayers to simulate\n",
    "\n",
    "Parameters['Dwell_Time'] = 10.0                     # Total pulse period (for PLD) or total deposition time (for MBE) in seconds.\n",
    "Parameters['Pulse_Shape'] = 'Uniform'              # Shape of the deposition pulse. Options: 'Uniform', 'Non_Uniform'\n",
    "Parameters['Pulse_Width'] = 1e-8                   # Width of deposition pulse (for PLD) or total deposition time (for MBE, set the same as dwell time) in seconds.\n",
    "\n",
    "Parameters['Post_Anneal'] = False                  # Run a Post Anneal Step (True/False)\n",
    "Parameters['Post_Anneal_Time'] = 100.0             # Length of Post Anneal step in seconds.\n",
    "\n",
    "\n",
    "\n",
    "# Density Map Model Parameters (Density map type simulations only)\n",
    "Parameters['Total_Sims'] = 1                        # total number of sims at each time\n",
    "\n",
    "\n",
    "\n",
    "# Diffusion Only Parameters (Diffusion type simulations only)\n",
    "Parameters['Diffusion_Type'] = 'Island'          # Type of diffusion sim to run. Options: 'Standard' - particles on surface, 'Island' - diffusing off island\n",
    "\n",
    "Parameters['Cluster'] = np.array([[0,1,2],[0,0,0]])       # set up cluster coordinates for surface diffusion\n",
    "Parameters['Cluster'] = np.array([[187],[100]])             # one particle in the middle\n",
    "\n",
    "Parameters['Sim_Time'] = 2.0            # simulation time in seconds (Standard Type only)\n",
    "\n",
    "Parameters['Particle_Number'] = 100              # how many particles to simulate (Island Type only)\n",
    "Parameters['Tracer_Number'] = 5                # how many tracer diffusion paths to save in simulation\n",
    "\n",
    "\n",
    "\n",
    "# Thermal Processes and Activation Energies (Slow Dynamics)\n",
    "Parameters['Enable_Processes'] = 'No_Uphill_4NN'      # Choose which processes to enable. Options: 'All', 'No_Uphill_4NN', 'No_Uphill', 'No_Detach', 'No_Edge'\n",
    "\n",
    "Parameters['w0'] = 10**13                       # Prefactor for Arrhenius law (Crystal Vibration Frequency: w0 ~ kT/h )\n",
    "Parameters['Substrate_Temperature'] = 600       # Substrate temperature in Celcius\n",
    "\n",
    "Parameters['Ea_diffusion'] = 1.8                # Energy Barrier for surface diffusion in eV\n",
    "Parameters['Ea_ehrlich_schwoebel'] = 0.0        # Energy Barrier for downhill/uphill diffusion in eV\n",
    "Parameters['Ea_detach'] = 0.25                 # Energy Barrier for detachment from one nearest neighbor in eV\n",
    "Parameters['Ea_edge'] = 10.0                     # Energy Barrier for Edge diffusion in eV (3D only). Value of 0.0 means same rate as surface diffusion\n",
    "Parameters['Ea_corner'] = 0.0                   # Energy Barrier for Corner diffusion in eV (3D only)\n",
    "\n",
    "\n",
    "\n",
    "# Non-Thermal Processes (Fast Dynamics)\n",
    "Parameters['Downward_Funneling'] = False      # enables downward funneling when particles land on step edges\n",
    "Parameters['Transient_Mobility'] = False      # enables transient mobility\n",
    "Parameters['Island_Chipping'] = False         # enable island chipping"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Evaluate the Input Parameters\n",
    "* print elementary process rates"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "Rate_Catalog, rates, moves, keys, num_proc = KMC_Proc.Process_Catalog(Parameters).Return_Rates()\n",
    "Rate_Catalog"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Run the Simulation\n",
    "* Pick a simulation script from below"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Single Simulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "Simulation = KMC_Main.Simulation(Parameters)   # Initialize the Simulation\n",
    "Simulation.Run()   # Run the Simulation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Multiple Sims - vary a parameter"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Vary the edge diffusion energy barrier and evaluate island morphology\n",
    "E_edge = np.arange(0.1,1.0,0.01)\n",
    "N = E_edge.shape[0]  # number of sims\n",
    "print (N)\n",
    "\n",
    "# Set surface diffusion\n",
    "Parameters['Ea_diffusion'] = 0.8\n",
    "\n",
    "Imgs = []  # store surface after each sim\n",
    "Clusters = []  # store final number of clusters\n",
    "\n",
    "Parameters['Enable_Plots'] = False\n",
    "Parameters['Enable_Print_Outs'] = False\n",
    "\n",
    "for i in range(N):\n",
    "    # reset parameters\n",
    "    Parameters['Ea_detach'] = E_edge[i]\n",
    "    Parameters['Simulation_Name'] = 'rPLD_Ea_'+str(E_edge[i])[:4]+'eV'\n",
    "\n",
    "    Simulation = KMC_Sim.Simulation(Parameters)\n",
    "    Simulation.Run()\n",
    "\n",
    "    num_clusters = Simulation.Pulse.Analysis.num_clusters[1][-1]\n",
    "    Clusters.append(num_clusters)\n",
    "\n",
    "    Rate_Catalog = Simulation.Pulse.Engine.rate_catalog\n",
    "    k1 = Rate_Catalog['Diff']\n",
    "\n",
    "    # get the final surface\n",
    "    Lattice = Simulation.Pulse.Engine.lattice\n",
    "    Surface = np.argmax(Lattice,axis=2)\n",
    "    Surface = Surface.astype(np.uint8)  # max layer is 256 for this dtype\n",
    "    Imgs.append(Surface)\n",
    "\n",
    "    time.sleep(2)  # precaution to prevent same Date-Time Stamp if fast simulation\n",
    "\n",
    "    print ('Sim',str(i+1),'out of',str(N),'Complete!')\n",
    "\n",
    "print ('Done!!!!!')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
